package com.zzyl.nursing.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.nursing.domain.pojo.Bed;
import com.zzyl.nursing.domain.pojo.Floor;
import com.zzyl.nursing.domain.pojo.Room;
import com.zzyl.nursing.domain.vo.FloorVo;
import com.zzyl.nursing.domain.vo.TreeVo;
import com.zzyl.nursing.mapper.BedMapper;
import com.zzyl.nursing.mapper.FloorMapper;
import com.zzyl.nursing.mapper.RoomMapper;
import com.zzyl.nursing.service.IFloorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 楼层Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-26
 */
@Service
public class FloorServiceImpl extends ServiceImpl<FloorMapper, Floor> implements IFloorService {
    @Autowired
    private FloorMapper floorMapper;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private BedMapper bedMapper;

    /**
     * 查询楼层
     *
     * @param id 楼层主键
     * @return 楼层
     */
    @Override
    public Floor selectFloorById(Long id) {
        return getById(id);
    }

    /**
     * 新增楼层
     *
     * @param floor 楼层
     * @return 结果
     */
    @Override
    public int insertFloor(Floor floor) {
        return save(floor) ? 1 : 0;
    }

    /**
     * 修改楼层
     *
     * @param floor 楼层
     * @return 结果
     */
    @Override
    public int updateFloor(Floor floor) {
        return updateById(floor) ? 1 : 0;
    }

    /**
     * 批量删除楼层
     *
     * @param ids 需要删除的楼层主键
     * @return 结果
     */
    @Override
    public int deleteFloorByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除楼层信息
     *
     * @param id 楼层主键
     * @return 结果
     */
    @Override
    public int deleteFloorById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 查询所有楼层（负责老人）
     */
    @Override
    public List<Floor> selectAllByNur() {
        return floorMapper.selectAllByNur();
    }

    /**
     * 查询所有床关联的楼，房信息
     *
     * @return
     */
    @Override
    public List<TreeVo> getRoomAndBedByBedStatus(Integer status) {
        // 方法一：三表联查，根据resultMap映射
     /*   List<TreeVo> roomAndBedByBedStatus = floorMapper.getRoomAndBedByBedStatus(status);
        return roomAndBedByBedStatus;
        */


        //方法二：三级联动(优化)，减少三表联查带来的一次性查询数据量过大，分次查询
        // 1 查询楼层List<Floor>，房间List<Room>，床List<Bed>的list集合
        // 1.1 查询所有的楼
        List<Floor> floorList = this.list();
        Set<Long> floorIdSet = floorList.stream().map(Floor::getId).collect(Collectors.toSet());

        // 1.2 查询所有的房间
        List<Room> roomList = roomMapper.selectList(Wrappers.<Room>lambdaQuery().in(Room::getFloorId, floorIdSet));
        Set<Long> roomIdSet = roomList.stream().map(Room::getId).collect(Collectors.toSet());

        // ----------若房间为空，直接返回所有楼的集合
        if (CollectionUtil.isEmpty(roomIdSet)) {
            return floorList.stream().map(floor -> TreeVo.builder()
                            .value(String.valueOf(floor.getId()))
                            .label(floor.getName())
                            .children(Collections.emptyList())
                            .build())
                    .collect(Collectors.toList());
        }

        // 1.3 查询所有的床
        List<Bed> bedList = bedMapper.selectList(Wrappers.<Bed>lambdaQuery()
                .in(Bed::getRoomId, roomIdSet)
                .eq(Bed::getBedStatus, 0));

        // 2 根据roomId构建Map<roomId，List<TreeVo> bedList> bedMap 集合对象,List<Bed>并根据roomId进行分组
        Map<Long, List<TreeVo>> bedMap = bedList.stream().collect(Collectors.groupingBy(Bed::getRoomId, Collectors.mapping(bed -> TreeVo
                .builder()
                .value(String.valueOf(bed.getId()))
                .label(bed.getBedNumber())
                .build(), Collectors.toList())));
        // 3 根据floorId构建Map<floorId,List<TreeVo> roomList> roomMap 集合，List<Room>根据floorId进行分组
        Map<Long, List<TreeVo>> roomMap = roomList.stream().collect(Collectors.groupingBy(Room::getFloorId, Collectors.mapping(room -> TreeVo
                .builder()
                .value(String.valueOf(room.getId()))
                .label(room.getCode())
                .children(bedMap.getOrDefault(room.getId(), Collections.emptyList()))
                .build(), Collectors.toList())));
        // 4 List<Floor> 循环遍历将每个floor对象转换为TreeVo对象，并收集到一个集合中，每个TreeVo对象中的children存放的是根据floorId分组的房间列表
        return floorList.stream().map(floor -> TreeVo
                .builder()
                .value(String.valueOf(floor.getId()))
                .label(floor.getName())
                .children(roomMap.getOrDefault(floor.getId(), Collections.emptyList()))
                .build()).collect(Collectors.toList());
    }

    @Override
    public List<FloorVo> getAllFloorsWithDevice() {
        return this.baseMapper.getAllFloorsWithDevice();
    }
}